// 项目的根组件
// React组件中获取/操作DOM 需要使用useRef钩子函数，分为两步：
// 第一步：使用useRef创建一个ref对象，并与jsx绑定
// const inputRef = useRef(null)
// <input type="text" ref={inputRef} />
// 第二步：在DOM可用时，通过inputRef.current获取DOM对象,渲染完毕之后DOM生成之后才可用
// console.log(inputRef.current)
import { useState, useRef, createContext, useContext } from 'react'

const MsgContext = createContext()

function Son1(props) {
  // props：对象里面包含了父组件传递过来的所有的数据
  console.log(props)
  return (
    <>
      <div>this is son，{props.name},jsx:{props.child},bname:{props.bname}</div>
    </>
  )
}
function Son2(props) {
  // props：对象里面包含了父组件传递过来的所有的数据
  console.log(props)
  return (
    <>
      <div>children:{props.children}</div>
    </>
  )
}
function Son3(props) {
  // props：对象里面包含了父组件传递过来的所有的数据
  console.log(props)
  const sonMsg = "this is a son3's msg"
  return (
    <>
      <div>
        <button onClick={() => { props.onGetMsg(sonMsg) }}>把数据传给父组件</button>
      </div>
    </>
  )
}

function A() {
  return (
    <div>this is A
      <B />
    </div>
  )
}

function B() {
  const name = useContext(MsgContext)
  return (
    <div>this is B
      {name}
    </div>
  )
}


function App() {

  const [value, setValue] = useState('')

  const inputRef = useRef(null)

  const showDom = () => {
    console.log(inputRef.current)
  }

  const name = "this is app name"

  const [bname, setBname] = useState('')
  const getMsg = (msg) => {
    console.log(msg)
    setBname(msg)
  }

  {/**----------------------------- */ }


  return (
    <div>
      <h1>day2</h1>
      <input
        type="text"
        value={value}
        onChange={(e) => { setValue(e.target.value) }}
      />
      <input
        type="text"
        ref={inputRef}
      />
      <button onClick={showDom} >获取DOM</button>
      <h3>------ 父传子:属性放在props中进行传递 ------</h3>
      {/* 父传子 */}
      {/* <Son1
        name={name}
        age={18}
        isTrue={true}
        list={['vue', 'react']}
        obj={{ name: 'zs', age: 18 }}
        fn={() => { console.log('fn') }}
        child={<span>this is a span</span>}
      /> */}
      <h3>------  父传子：把内容放在标签中时，父组件会在props中封装一个children对象 ------</h3>
      <Son2>
        <span>把内容嵌套在子组件的标签中时，父组件会自动添加名为children中对象</span>
      </Son2>
      {/*  子传父 
        通过函数回调的方式
      */}
      <h3>------ 子传父：通过方法回调传递数据 ------</h3>
      <Son3 onGetMsg={getMsg} />

      {/* 兄弟通信 */}
      <h3>------ 兄弟通信：通过共同的父组件进行通信 Son3传给Son1------</h3>
      <Son3 onGetMsg={getMsg} />
      <Son1 bname={bname} />
      {/** 跨层组件传递 */}
      <h3>------ 跨层组件传递 ---------------------</h3>
      <MsgContext.Provider value={name}>

        <A />
      </MsgContext.Provider>
    </div>
  )
}

export default App;